/**
 * 
 */
package com.dragonwarriors.player;

import java.awt.Dimension;

import com.ahq.main.DWHPBorder;
import com.dalonedrau.jogl.engine.GameApplet;
import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.opengl.sprite.BasicSpriteObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteBase;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObjectFactory;
import com.dalonedrau.jogl.opengl.ui.GuiComponent;
import com.dalonedrau.jogl.opengl.ui.Label;
import com.dalonedrau.jogl.opengl.ui.UIFactory;
import com.dalonedrau.jogl.opengl.ui.border.StatsBorder;
import com.dalonedrau.jogl.opengl.ui.border.EmptyBorder;
import com.dalonedrau.jogl.opengl.ui.border.FlexibleImageBorder;
import com.dalonedrau.jogl.opengl.ui.border.GradientBackgroundBorder;
import com.dalonedrau.jogl.opengl.ui.panel.LandscapePagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.PagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.Panel;
import com.dalonedrau.jogl.opengl.ui.panel.PortraitPagePanel;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;
import com.dalonedrau.watchable.Watchable;
import com.dalonedrau.watchable.Watcher;

/**
 * Private inner class holding UI items for the character's characteristics and
 * health values. The UI panel is 182px wide, 175px high.
 * @author Donald
 */
final class CharacteristicsHealthPanel extends PortraitPagePanel {
	/** the top panel containing the hp, mp, xp scores. */
	private PagePanel	bottom;
	/** the experience points value label. */
	private Label		lblExperiencePoints;
	/** the health points value label. */
	private Label		lblHealthPoints;
	/** the intelligence value label. */
	private Label		lblIntelligence;
	/** the looks value label. */
	private Label		lblLooks;
	/** the magic points value label. */
	private Label		lblMagicPoints;
	/** the "Magic Points" title label. */
	private Label		lblMP;
	/** the psychic talent value label. */
	private Label		lblPsychicTalent;
	/** the reflexes value label. */
	private Label		lblReflexes;
	/** the "Reflexes" title label. */
	private Label		lblRFX;
	/** the strength value label. */
	private Label		lblStrength;
	/** the top panel containing the characteristic scores. */
	private PagePanel	top;
	/**
	 * Creates a new instance of {@link CharacteristicsHealthPanel}.
	 */
	protected CharacteristicsHealthPanel() {
		super(Panel.PORTRAIT_CENTER);
		try {
			final int h = 95;
			// build top inner panel, totaling 182px wide, 105px high
			top = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
			// inner col1 is 140px wide, 95px high
			top.addChild(buildInnerCol1());
			// 5px space
			Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
			lbl1.setBorder(new EmptyBorder(h, GlobalConsts.INT_005, 0, 0));
			top.addChild(lbl1);
			// inner col2 is 24px wide, 95px high
			top.addChild(buildInnerCol2());
			setTopBorder(DWPCViewer.getInstance().getBorderType());

			// build top inner panel - 119px wide, 70px high
			final int w = 182;
			bottom = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
			// set the preferred width so this lines up underneath the top row
			bottom.setPreferredWidth(w);
			bottom.setHorizontalAlignment(GuiComponent.TEXT_JUSTIFY);
			// inner col1 is 20px wide, 57px high
			bottom.addChild(buildInnerCol3());
			// inner col4 is 78px wide, 57px high
			bottom.addChild(buildInnerCol4());
			setBottomBorder(DWPCViewer.getInstance().getBorderType());

			top.setMinimumWidth(bottom.getPreferredSize().width);
			top.getPreferredSize().width = 0;
			top.getPreferredSize();
			super.addChild(top);
			super.addChild(bottom);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Builds the inner column holding the characteristics field labels. The
	 * resulting panel is 140px wide, 95px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol1() {
		PagePanel innercol1 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);
		Label l1 = UIFactory.getInstance().getStandardH1Label("Strength");
		l1.setTooltipText("the character's fitness and physical toughness");
		innercol1.addChild(l1);

		lblRFX = UIFactory.getInstance().getStandardH1Label("Reflexes");
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("the character's dexterity, agility, and the ");
		sb.append("speed of his or her reactions");
		lblRFX.setTooltipText(sb.toString());
		sb.setLength(0);
		innercol1.addChild(lblRFX);

		Label l2 = UIFactory.getInstance().getStandardH1Label("Intelligence");
		l2.setTooltipText("the measure of the character's cleverness");
		innercol1.addChild(l2);

		Label l3 = UIFactory.getInstance().getStandardH1Label("Psychic Talent");
		sb.append("the character's basic ability to resist or use magic");
		l3.setTooltipText(sb.toString());
		sb.returnToPool();
		innercol1.addChild(l3);

		Label l4 = UIFactory.getInstance().getStandardH1Label("Looks");
		l4.setTooltipText("the character's appearance and personal charm");
		innercol1.addChild(l4);

		return innercol1;
	}
	/**
	 * Builds the inner column holding the characteristics values. The resulting
	 * panel is 24px wide, 95px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol2() {
		PagePanel innercol2 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);
		lblStrength = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblStrength);

		lblReflexes = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblReflexes);

		lblIntelligence = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblIntelligence);

		lblPsychicTalent = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblPsychicTalent);

		lblLooks = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblLooks);

		return innercol2;
	}
	/**
	 * Builds the inner column holding the hp, mp, and xp field labels. The
	 * resulting panel is 20px wide, 57px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol3() {
		PagePanel innercol3 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		Label l1 = UIFactory.getInstance().getStandardH1Label("HP");
		innercol3.addChild(l1);

		final int w = 20, h = 19;
		lblMP = UIFactory.getInstance().getStandardH1Label("");
		lblMP.setMinimumSize(w, h);
		innercol3.addChild(lblMP);

		Label l2 = UIFactory.getInstance().getStandardH1Label("XP");
		innercol3.addChild(l2);

		return innercol3;
	}
	/**
	 * Builds the inner column holding the hp, mp, and xp values. The resulting
	 * panel is 78px wide, 57px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol4() {
		PagePanel innercol4 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		final int w = 78, h = 19;
		lblHealthPoints = DWPCViewer.getInstance().getDWHPLabel();
		innercol4.addChild(lblHealthPoints);

		lblMagicPoints = UIFactory.getInstance().getStandardH2Label("");
		lblMagicPoints.setMaximumSize(w, h);
		lblMagicPoints.setMinimumSize(w, h);
		innercol4.addChild(lblMagicPoints);

		lblExperiencePoints = DWPCViewer.getInstance().getDWHPLabel();
		innercol4.addChild(lblExperiencePoints);

		return innercol4;
	}
	/**
	 * Sets the border type used, either for the standalone dialog or integrated
	 * with the character creations screen.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	public void setBorderType(final int val) throws Exception {
		setTopBorder(val);
		setBottomBorder(val);
	}
	/**
	 * Sets the border type used for the bottom panel.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	private void setBottomBorder(final int val) throws Exception {
		switch (val) {
		case 1:
			// add bottom panel's border, 16px wide, 13px high
			bottom.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_bl"), // bottom-left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_br_half_2"), // b-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_b"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tl_full"), // top-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tr_half"), // top-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_t_1"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_005, // top
							GlobalConsts.INT_008, // left
							GlobalConsts.INT_008, // bottom
							GlobalConsts.INT_005 // right
					}
					));
			break;
		default:
			// add bottom panel's border, 16px wide, 13px high
			bottom.setBorder(new FlexibleImageBorder(
						new int[] {
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_bl_half_2"), // bottom-l
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_br_half_2"), // b-r
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_border_b"), // bottom
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tl_half"), // tl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tr_half"), // top-r
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_t_1"), // top
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_l"), // left
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_r") // right
					},
						new int[] {
								GlobalConsts.INT_005, // top
								GlobalConsts.INT_008, // left
								GlobalConsts.INT_008, // bottom
								GlobalConsts.INT_005 // right
					}
					));
		}
	}
	/**
	 * Sets the border type used for the top panel.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	private void setTopBorder(final int val) throws Exception {
		switch (val) {
		case 1:
			// add top panel's border, 13px wide, 10px high
			top.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_bl_full"), // b-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_br_half"), // b-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_b_1"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tl_full"), // top-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tr_half"), // top-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_t_1"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_005, // top
							GlobalConsts.INT_008, // left
							GlobalConsts.INT_005, // bottom
							GlobalConsts.INT_005 // right
					}
					));
			break;
		default:
			// add top panel's border - 10px wide by 10px high
			top.setBorder(new FlexibleImageBorder(
						new int[] {
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_bl_half"), // bl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_br_half"), // br
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_b_1"), // bottom
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tl_half"), // tl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tr_half"), // tr
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_t_1"), // top
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_l"), // left
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_r") // right
					},
						new int[] {
								GlobalConsts.INT_005, // top
								GlobalConsts.INT_005, // left
								GlobalConsts.INT_005, // bottom
								GlobalConsts.INT_005 // right
					}
					));
			break;
		}
	}
	/**
	 * Updates all labels.
	 * @param pc the {@link DWCharacter} displayed
	 */
	protected void update(final DWCharacter pc) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		if (pc == null) {
			lblStrength.setText("");
			lblReflexes.setText("");
			sb.append("the character's dexterity, agility, and the ");
			sb.append("speed of his or her reactions");
			lblRFX.setTooltipText(sb.toString());
			lblIntelligence.setText("");
			lblPsychicTalent.setText("");
			lblLooks.setText("");
			lblHealthPoints.setText("");
			lblMP.setText("");
			lblMagicPoints.setText("");
			if (lblMagicPoints.getBorder() != null) {
				lblMagicPoints.setBorder(null);
			}
			lblExperiencePoints.setText("");
		} else {
			if (pc.getFullStrength() >= 0
					&& pc.getFullReflexes() >= 0
					&& pc.getFullIntelligence() >= 0
					&& pc.getFullPsychicTalent() >= 0
					&& pc.getFullLooks() >= 0) {
				lblStrength.setText(Integer.toString(pc.getFullStrength()));
				lblReflexes.setText(Integer.toString(pc.getFullReflexes()));
				sb.append("the character's dexterity, agility, and the speed of ");
				sb.append(DWConsts.GENDER_POSSESSIVE[pc.getGender()]);
				sb.append(" reactions");
				lblRFX.setTooltipText(sb.toString());
				sb.setLength(0);
				lblIntelligence.setText(Integer.toString(pc
						.getFullIntelligence()));
				lblPsychicTalent.setText(
						Integer.toString(pc.getFullPsychicTalent()));
				lblLooks.setText(Integer.toString(pc.getFullLooks()));
			} else {
				lblStrength.setText("");
				lblReflexes.setText("");
				sb.append("the character's dexterity, agility, and the ");
				sb.append("speed of his or her reactions");
				lblRFX.setTooltipText(sb.toString());
				lblIntelligence.setText("");
				lblPsychicTalent.setText("");
				lblLooks.setText("");
			}
			if (pc.getProfession() >= 0) {
				sb.append(pc.getFullHealthPoints());
				sb.append("/");
				sb.append(pc.getFullMaxHealthPoints());
				lblHealthPoints.setText(sb.toString());
				sb.setLength(0);

				if (pc.getProfession() != DWConsts.PROF_ASSASSIN
						&& pc.getProfession() != DWConsts.PROF_BARBARIAN
						&& pc.getProfession() != DWConsts.PROF_KNIGHT
						&& pc.getProfession() != DWConsts.PROF_MYSTIC) {
					lblMP.setText("MP");
					if (lblMagicPoints.getBorder() == null) {
						lblMagicPoints
								.setBorder(new DWHPBorder(lblMagicPoints));
					}
					sb.append(pc.getFullMagicPoints());
					sb.append("/");
					sb.append(pc.getFullMaxMagicPoints());
					lblMagicPoints.setText(sb.toString());
					sb.setLength(0);
				} else {
					lblMP.setText("");
					lblMagicPoints.setText("");
					if (lblMagicPoints.getBorder() != null) {
						lblMagicPoints.setBorder(null);
					}
				}
				lblExperiencePoints.setText(Integer.toString(pc.getXp()));
			} else {
				lblHealthPoints.setText("");
				lblMP.setText("");
				lblMagicPoints.setText("");
				if (lblMagicPoints.getBorder() != null) {
					lblMagicPoints.setBorder(null);
				}
				lblExperiencePoints.setText("");
			}
		}
		sb.returnToPool();
	}
}

/**
 * @author Donald
 */
public final class DWPCViewer extends PortraitPagePanel implements Watcher {
	/** the one and only instance of the <code>Sprite</code> class. */
	private static DWPCViewer	instance;
	/**
	 * Sprite Gives access to the singleton instance of {@link Sprite}.
	 * @return {@link Sprite}
	 */
	public static DWPCViewer getInstance() {
		if (DWPCViewer.instance == null) {
			DWPCViewer.instance = new DWPCViewer();
			DWPCViewer.instance.init();
		}
		return DWPCViewer.instance;
	}
	/**
	 * the border type used, either part of the char creator screen or
	 * stand-alone.
	 */
	private int							borderType	= 0;
	/** the {@link DWCharacter} displayed. */
	private DWCharacter					pc;
	/** the characteristics and health panel. */
	private CharacteristicsHealthPanel	pnlCharHealth;
	/** the name and rank panel. */
	private NameRankProfessionPanel		pnlNameRank;
	/** the other factors panel. */
	private OtherFactorsPanel			pnlOtherFactors;
	/** the second row. */
	private PagePanel					rowTwo;
	/** Hidden constructor. */
	private DWPCViewer() {
		super(Panel.PORTRAIT_CENTER);
		super.setBorder(new GradientBackgroundBorder());
	}
	/**
	 * Gets the border type.
	 * @return {@link int}
	 */
	public int getBorderType() {
		return borderType;
	}
	/**
	 * Gets a "hp" type label for display in the viewer.
	 * @return {@link Label}
	 */
	public Label getDWHPLabel() {
		final int w = 78, h = 19;
		Label lbl = UIFactory.getInstance().getStandardH2Label("");
		lbl.setMaximumSize(w, h);
		lbl.setMinimumSize(w, h);
		lbl.setBorder(new DWHPBorder(lbl));
		return lbl;
	}
	/**
	 * Gets a "stats" label for display in the viewer.
	 * @return {@link Label}
	 */
	public Label getDWStatsLabel() {
		final int w = 24, h = 19;
		Label lbl = UIFactory.getInstance().getStandardH2Label("");
		lbl.setMaximumSize(w, h);
		lbl.setMinimumSize(w, h);
		lbl.setBorder(new StatsBorder(lbl));
		return lbl;
	}
	/**
	 * Gets the {@link DWCharacter} displayed.
	 * @return {@link DWCharacter}
	 */
	public DWCharacter getPc() {
		return pc;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public Dimension getPreferredSize() {
		if (super.getPreferredSize().width == 0
				|| super.getPreferredSize().height == 0) {
			int w = 0, h = 0;
			if (getBorder() != null) {
				w = getBorder().getInsets().left;
				w += getBorder().getInsets().right;
				h = getBorder().getInsets().top;
				h += getBorder().getInsets().bottom;
			}
			w += getInsets().left + getInsets().right;
			h += getInsets().top + getInsets().bottom;
			// size up children
			int maxChildW = 0;
			for (int i = 0; i < super.getChildren().length; i++) {
				maxChildW = Math.max(maxChildW,
						super.getChildren()[i].getPreferredSize().width);
				h += super.getChildren()[i].getPreferredSize().height;
			}
			w += maxChildW;
			// set widths for children
			for (int i = 0; i < super.getChildren().length; i++) {
				super.getChildren()[i].setPreferredSize(maxChildW,
						super.getChildren()[i].getPreferredSize().height);
			}

			super.getPreferredSize().width = w;
			super.getPreferredSize().height = h;
		}
		if (getBorder() != null) {
			if (!(getBorder().getPreferredSize() != null
					&& getBorder().getPreferredSize().width == super
							.getPreferredSize().width && getBorder()
					.getPreferredSize().height == super.getPreferredSize().height)) {
				getBorder().setPreferredSize(super.getPreferredSize().width,
						super.getPreferredSize().height);
			}
		}
		return super.getPreferredSize();
	}
	/** Initializes the viewer. */
	private void init() {
		try {
			// 374px by 54px
			pnlNameRank = new NameRankProfessionPanel();
			// 182px by 175px
			pnlCharHealth = new CharacteristicsHealthPanel();
			// 192px by 166px
			pnlOtherFactors = new OtherFactorsPanel();

			refactor();
			super.addChild(pnlNameRank);

			rowTwo = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
			rowTwo.addChild(pnlCharHealth);
			rowTwo.addChild(pnlOtherFactors);
			super.addChild(rowTwo);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	private void refactor() {
		pnlNameRank.setMinimumWidth(
				pnlCharHealth.getPreferredSize().width
						+ pnlOtherFactors.getPreferredSize().width);
		pnlNameRank.setMaximumWidth(
				pnlCharHealth.getPreferredSize().width
						+ pnlOtherFactors.getPreferredSize().width);
		pnlNameRank.getPreferredSize().width = 0;
		pnlNameRank.getPreferredSize();
		super.getPreferredSize().width = 0;
		super.getPreferredSize();
	}
	/**
	 * Sets the border type.
	 * @param val the val to set
	 */
	public void setBorderType(final int val) {
		borderType = val;
		try {
			pnlCharHealth.setBorderType(val);
			pnlNameRank.setBorderType(val);
			pnlOtherFactors.setBorderType(val);
			refactor();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Sets the {@link DWCharacter} displayed.
	 * @param val the {@link DWCharacter} to set
	 */
	public void setPc(final DWCharacter val) {
		pc = val;
		pc.addWatcher(this);
		watchUpdated(pc);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void watchUpdated(final Watchable data) {
		try {
			if (pc != null) {
				pnlNameRank.update(pc);
				pnlCharHealth.update(pc);
				pnlOtherFactors.update(pc);
			} else {
				DWCharacter c = (DWCharacter) data;
				pnlNameRank.update(c);
				pnlCharHealth.update(c);
				pnlOtherFactors.update(c);
			}

			// force a re-positioning of all data
			super.getPreferredSize().width = 0;
			pnlNameRank.getPreferredSize().width = 0;
			pnlCharHealth.getPreferredSize().width = 0;
			// pnlOtherFactors.getPreferredSize().width = 0;
			rowTwo.getPreferredSize().width = 0;
			getPreferredSize();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
}

/**
 * Private inner class holding UI items for the character's name and profession
 * values. The UI panel is 346px wide, 54px high.
 * @author Donald
 */
final class NameRankProfessionPanel extends PortraitPagePanel {
	/** the gender label. */
	private Label	lblGender;
	/** the name label. */
	private Label	lblName;
	/** the profession label. */
	private Label	lblProfession;
	/** the rank label. */
	private Label	lblRank;
	/**
	 * Creates a new instance of {@link CharacteristicsHealthPanel}.
	 */
	protected NameRankProfessionPanel() {
		super(Panel.PORTRAIT_CENTER);
		try {
			// inner col1 is 358px wide, 19px high
			super.addChild(buildInnerRow1());
			// 3px space
			Label lbl0 = UIFactory.getInstance().getStandardH1Label("");
			lbl0.setBorder(new EmptyBorder(GlobalConsts.INT_003, 358, 0, 0));
			super.addChild(lbl0);
			// inner col1 is 358px wide, 19px high
			// buildInnerRow2();
			super.addChild(buildInnerRow2());
			setBorderType(DWPCViewer.getInstance().getBorderType());
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Builds the inner column holding the name and gender labels. The resulting
	 * panel is 220px wide, 19px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerRow1() {
		PagePanel innerrow1 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		innerrow1.setHorizontalAlignment(GuiComponent.CENTER);
		final int w = 358;
		// set the preferred width so this lines up underneath the top row
		innerrow1.setPreferredWidth(w);
		final int w1 = 17, w2 = 13, h = 19;
		// GENDER - 17px
		lblGender = UIFactory.getInstance().getStandardH1Label("");
		lblGender.setMaximumSize(w1, h);
		lblGender.setMinimumSize(w2, h);
		innerrow1.addChild(lblGender);
		// 10px space
		Label lbl0 = UIFactory.getInstance().getStandardH1Label("");
		lbl0.setBorder(new EmptyBorder(h, GlobalConsts.INT_010, 0, 0));
		innerrow1.addChild(lbl0);
		// NAME - 200px
		lblName = UIFactory.getInstance().getStandardH1Label("");
		innerrow1.addChild(lblName);

		return innerrow1;
	}
	/**
	 * Builds the inner column holding the rank and profession labels. The
	 * resulting panel is 330px wide, 19px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerRow2() {
		PagePanel innerrow2 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		innerrow2.setHorizontalAlignment(GuiComponent.CENTER);
		final int w = 358;
		// set the preferred width so this lines up underneath the top row
		innerrow2.setPreferredWidth(w);
		final int h = 19;
		// RANK - 90px
		lblRank = UIFactory.getInstance().getStandardH1Label("");
		innerrow2.addChild(lblRank);
		// 10px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(h, GlobalConsts.INT_010, 0, 0));
		innerrow2.addChild(lbl2);
		// PROFESSION - 230px
		lblProfession = UIFactory.getInstance().getStandardH1Label("");
		innerrow2.addChild(lblProfession);

		return innerrow2;
	}
	/**
	 * Sets the border type used, either for the standalone dialog or integrated
	 * with the character creations screen.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	public void setBorderType(final int val) throws Exception {
		switch (val) {
		case 1:
			// add border - 16px wide by 13px high
			super.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_bl_full"), // b-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_br_0"), // bottom-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_b_1"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_tl"), // top-left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_tr"), // top-right
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_t"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_008, // top
							GlobalConsts.INT_008, // left
							GlobalConsts.INT_005, // bottom
							GlobalConsts.INT_008 // right
					}
					));
			break;
		default:// add border - 10px wide by 10px high
			super.setBorder(new FlexibleImageBorder(
						new int[] {
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_bl_half"), // bl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_br_half"), // br
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_b_1"), // bottom
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tl_half"), // tl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tr_half"), // tr
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_t_1"), // top
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_l"), // left
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_r") // right
					},
						new int[] {
								GlobalConsts.INT_005, // top
								GlobalConsts.INT_005, // left
								GlobalConsts.INT_005, // bottom
								GlobalConsts.INT_005 // right
					}
					));
			break;
		}
	}
	/**
	 * Updates all labels.
	 * @param pc the {@link DWCharacter} displayed
	 */
	protected void update(final DWCharacter pc) {
		try {
			PooledStringBuilder sb =
					StringBuilderPool.getInstance().getStringBuilder();
			if (pc == null) {
				lblName.setText("");
				if (lblGender.getSprite() != null) {
					lblGender.getSprite().assignFlag(
							SpriteBase.FLAG_SPRITE_DO_NOT_RENDER);
				}
				lblRank.setText("");
				lblProfession.setText("");
			} else {
				if (pc.getName() != null
						&& pc.getName().length > 0) {
					for (int i = 0; i < pc.getName().length; i++) {
						sb.append(pc.getName()[i]);
					}
					lblName.setText(sb.toString());
					sb.setLength(0);
				} else {
					lblName.setText("");
				}

				if (pc.getGender() >= 0) {
					SpriteImageObject img =
							SpriteImageObjectFactory.getInstance()
									.getImageByName(
											"icon_male");
					if (pc.getGender() == DWConsts.GENDER_FEMALE) {
						img = SpriteImageObjectFactory.getInstance()
								.getImageByName(
										"icon_female");
					}
					SpriteBase sprite = lblGender.getSprite();
					if (sprite == null) {
						sprite = new BasicSpriteObject();
						sprite.setImageRefId(img.getRefId());
						sprite.setWidth(img.getWidth());
						sprite.setHeight(img.getHeight());
						lblGender.setSprite(sprite);
					} else {
						sprite.removeFlag(SpriteBase.FLAG_SPRITE_DO_NOT_RENDER);
						if (sprite.getImageRefId() != img.getRefId()) {
							sprite.setImageRefId(img.getRefId());
							sprite.setWidth(img.getWidth());
							sprite.setHeight(img.getHeight());
							lblGender.getPreferredSize().width = 0;
						}
					}
				} else {
					if (lblGender.getSprite() != null) {
						lblGender.getSprite().assignFlag(
								SpriteBase.FLAG_SPRITE_DO_NOT_RENDER);
					}
				}

				if (pc.getRank() > 0) {
					lblRank.setText(DWPlayer.getInstance().getRankString(pc));
				} else {
					lblRank.setText("");
				}

				if (pc.getProfession() >= 0) {
					int l = DWConsts.PROFESSIONS[pc.getProfession()].length;
					for (int i = 0; i < l; i++) {
						sb.append(DWConsts.PROFESSIONS[pc.getProfession()][i]);
					}
					lblProfession.setText(sb.toString());
				} else {
					lblProfession.setText("");
				}
			}
			sb.returnToPool();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
}

/**
 * Private inner class holding UI items for the character's name and profession
 * values. The UI panel is 192px wide, 166px high.
 * @author Donald
 */
final class OtherFactorsPanel extends PortraitPagePanel {
	/** the bottom panel containing the magical attack and defence scores. */
	private PagePanel	bottom;
	/** the attack label. */
	private Label		lblAttack;
	/** the defense label. */
	private Label		lblDefense;
	/** the evasion label. */
	private Label		lblEvasion;
	/** the "Magical Attack" title label. */
	private Label		lblMA;
	/** the magical attack label. */
	private Label		lblMagicalAttack;
	/** the magical defense label. */
	private Label		lblMagicalDefense;
	/** the "Perception" title label. */
	private Label		lblPER;
	/** the perception label. */
	private Label		lblPerception;
	/** the stealth label. */
	private Label		lblStealth;
	/** the middle panel containing evasion, stealth, and perception. */
	private PagePanel	middle;
	/** the top panel containing the attack and defence scores. */
	private PagePanel	top;
	/**
	 * Creates a new instance of {@link CharacteristicsHealthPanel}.
	 */
	protected OtherFactorsPanel() {
		super(Panel.PORTRAIT_CENTER);
		try {
			// build top inner panel, totaling 115px wide, 51px high
			top = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
			top.setHorizontalAlignment(GuiComponent.TEXT_JUSTIFY);
			// set the preferred width so this lines up underneath the top row
			final int w = 192;
			top.setPreferredWidth(w);
			// inner col1 is 70px wide, 41px high
			top.addChild(buildInnerCol1());
			// inner col1 is 24px wide, 41px high
			top.addChild(buildInnerCol2());
			setTopBorder(DWPCViewer.getInstance().getBorderType());
			super.addChild(top);
			// build middle inner panel, totaling 145px wide, 71px high
			middle = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
			middle.setHorizontalAlignment(GuiComponent.TEXT_JUSTIFY);
			// set the preferred width so this lines up underneath the top row
			middle.setPreferredWidth(w);
			// inner col3 is 100px wide, 61px high
			middle.addChild(buildInnerCol3());
			// inner col4 is 24px wide, 61px high
			middle.addChild(buildInnerCol4());
			setMiddleBorder(DWPCViewer.getInstance().getBorderType());
			super.addChild(middle);
			// build bottom inner panel, totaling 192px wide, 53px high
			bottom = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
			// set the preferred width so this lines up underneath the top row
			bottom.setPreferredWidth(w);
			// inner col5 is 150px wide, 40px high
			bottom.addChild(buildInnerCol5());
			// 5px space
			Label lbl6 = UIFactory.getInstance().getStandardH1Label("");
			lbl6.setBorder(new EmptyBorder(40, GlobalConsts.INT_005, 0, 0));
			bottom.addChild(lbl6);
			// inner col6 is 24px wide, 40px high
			bottom.addChild(buildInnerCol6());
			setBottomBorder(DWPCViewer.getInstance().getBorderType());
			super.addChild(bottom);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Builds the inner column holding the attack/defence field labels. The
	 * resulting panel is 70px wide, 41px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol1() {
		PagePanel innercol1 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		// 1px space
		Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
		lbl1.setBorder(new EmptyBorder(1, 1, 0, 0));
		innercol1.addChild(lbl1);

		Label l1 = UIFactory.getInstance().getStandardH1Label("Attack");
		innercol1.addChild(l1);

		Label l2 = UIFactory.getInstance().getStandardH1Label("Defence");
		innercol1.addChild(l2);

		// 2px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(2, 2, 0, 0));
		innercol1.addChild(lbl2);

		return innercol1;
	}
	/**
	 * Builds the inner column holding the attack/defence values. The resulting
	 * panel is 24px wide, 41px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol2() {
		PagePanel innercol2 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		// 1px space
		Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
		lbl1.setBorder(new EmptyBorder(1, 1, 0, 0));
		innercol2.addChild(lbl1);

		lblAttack = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblAttack);

		lblDefense = DWPCViewer.getInstance().getDWStatsLabel();
		innercol2.addChild(lblDefense);

		// 2px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(2, 2, 0, 0));
		innercol2.addChild(lbl2);

		return innercol2;
	}
	/**
	 * Builds the inner column holding the other factors field labels. The
	 * resulting panel is 100px wide, 61px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol3() {
		PagePanel innercol3 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		// 2px space
		Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
		lbl1.setBorder(new EmptyBorder(2, 2, 0, 0));
		innercol3.addChild(lbl1);

		Label l1 = UIFactory.getInstance().getStandardH1Label("Evasion");
		l1.setTooltipText("how good the character is at dodging");
		innercol3.addChild(l1);

		Label l2 = UIFactory.getInstance().getStandardH1Label("Stealth");
		l2.setTooltipText("the character's ability to maneuver unnoticed");
		innercol3.addChild(l2);

		lblPER = UIFactory.getInstance().getStandardH1Label("Perception");
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("the character's awareness of ");
		sb.append("his or her surroundings");
		lblPER.setTooltipText(sb.toString());
		sb.returnToPool();
		innercol3.addChild(lblPER);

		// 2px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(2, 2, 0, 0));
		innercol3.addChild(lbl2);

		return innercol3;
	}
	/**
	 * Builds the inner column holding the other factors values. The resulting
	 * panel is 24px wide, 61px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol4() {
		PagePanel innercol4 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		// 2px space
		Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
		lbl1.setBorder(new EmptyBorder(2, 2, 0, 0));
		innercol4.addChild(lbl1);

		lblEvasion = DWPCViewer.getInstance().getDWStatsLabel();
		innercol4.addChild(lblEvasion);

		lblStealth = DWPCViewer.getInstance().getDWStatsLabel();
		innercol4.addChild(lblStealth);

		lblPerception = DWPCViewer.getInstance().getDWStatsLabel();
		innercol4.addChild(lblPerception);

		// 2px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(2, 2, 0, 0));
		innercol4.addChild(lbl2);

		return innercol4;
	}
	/**
	 * Builds the inner column holding the magical attack/defence field labels.
	 * The resulting panel is 150px wide, 40px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol5() {
		PagePanel innercol5 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		// 1px space
		Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
		lbl1.setBorder(new EmptyBorder(1, 1, 0, 0));
		innercol5.addChild(lbl1);

		final int w = 150, h = 19;
		lblMA = UIFactory.getInstance().getStandardH1Label("");
		lblMA.setMinimumSize(w, h);
		innercol5.addChild(lblMA);

		Label l2 =
				UIFactory.getInstance().getStandardH1Label("Magical Defence");
		innercol5.addChild(l2);

		// 1px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(1, 1, 0, 0));
		innercol5.addChild(lbl2);

		return innercol5;
	}
	/**
	 * Builds the inner column holding the magical attack/defence values. The
	 * resulting panel is 24px wide, 40px high.
	 * @return {@link PagePanel}
	 */
	private PagePanel buildInnerCol6() {
		PagePanel innercol6 = new PortraitPagePanel(Panel.PORTRAIT_LEFT);

		// 1px space
		Label lbl1 = UIFactory.getInstance().getStandardH1Label("");
		lbl1.setBorder(new EmptyBorder(1, 1, 0, 0));
		innercol6.addChild(lbl1);

		final int w = 24, h = 19;
		lblMagicalAttack = UIFactory.getInstance().getStandardH2Label("");
		lblMagicalAttack.setMaximumSize(w, h);
		lblMagicalAttack.setMinimumSize(w, h);
		innercol6.addChild(lblMagicalAttack);

		lblMagicalDefense = DWPCViewer.getInstance().getDWStatsLabel();
		innercol6.addChild(lblMagicalDefense);

		// 1px space
		Label lbl2 = UIFactory.getInstance().getStandardH1Label("");
		lbl2.setBorder(new EmptyBorder(1, 1, 0, 0));
		innercol6.addChild(lbl2);

		return innercol6;
	}
	/**
	 * Sets the border type used, either for the standalone dialog or integrated
	 * with the character creations screen.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	public void setBorderType(final int val) throws Exception {
		setTopBorder(val);
		setMiddleBorder(val);
		setBottomBorder(val);
	}
	/**
	 * Sets the border type used for the bottom panel.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	private void setBottomBorder(final int val) throws Exception {
		switch (val) {
		case 1:
			// add bottom panel's border, 13px wide, 13px high
			bottom.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_bl_half_2"), // bottom-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_br"), // bottom-right
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_b"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tl_half"), // top-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tr_0"), // top-right
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_t_1"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_005, // top
							GlobalConsts.INT_005, // left
							GlobalConsts.INT_008, // bottom
							GlobalConsts.INT_008 // right
					}
					));
			break;
		default:
			// add bottom panel's border, 10px wide, 13px high
			bottom.setBorder(new FlexibleImageBorder(
						new int[] {
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_bl_half_2"), // bottom-l
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_br_half_2"), // b-r
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_border_b"), // bottom
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tl_half"), // top-l
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tr_half"), // tr
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_t_1"), // top
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_l"), // left
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_r") // right
					},
						new int[] {
								GlobalConsts.INT_005, // top
								GlobalConsts.INT_005, // left
								GlobalConsts.INT_008, // bottom
								GlobalConsts.INT_005 // right
					}
					));
			break;
		}
	}
	/**
	 * Sets the border type used for the middle panel.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	private void setMiddleBorder(final int val) throws Exception {
		switch (val) {
		case 1:
			// add middle panel's border, 13px wide, 10px high
			middle.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_bl_half"), // bl
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_br_0"), // b-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_b_1"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tl_half"), // tl
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tr_0"), // top-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_t_1"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_005, // top
							GlobalConsts.INT_005, // left
							GlobalConsts.INT_005, // bottom
							GlobalConsts.INT_008 // right
					}
					));
			break;
		default:
			// add middle panel's border - 10px wide by 10px high
			middle.setBorder(new FlexibleImageBorder(
						new int[] {
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_bl_half"), // bl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_br_half"), // br
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_b_1"), // bottom
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tl_half"), // tl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tr_half"), // tr
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_t_1"), // top
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_l"), // left
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_r") // right
					},
						new int[] {
								GlobalConsts.INT_005, // top
								GlobalConsts.INT_005, // left
								GlobalConsts.INT_005, // bottom
								GlobalConsts.INT_005 // right
					}
					));
			break;
		}
	}
	/**
	 * Sets the border type used for the top panel.
	 * @param val the value
	 * @throws Exception if an error occurs
	 */
	private void setTopBorder(final int val) throws Exception {
		switch (val) {
		case 1:
			// add top panel's border, 13px wide, 10px high
			top.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_bl_half"), // bl
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_br_0"), // b-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_b_1"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tl_half"), // tl
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tr_0"), // top-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_t_1"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_005, // top
							GlobalConsts.INT_005, // left
							GlobalConsts.INT_005, // bottom
							GlobalConsts.INT_008 // right
					}
					));
			break;
		default:
			// add top panel's border - 10px wide by 10px high
			top.setBorder(new FlexibleImageBorder(
						new int[] {
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_bl_half"), // bl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_br_half"), // br
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_b_1"), // bottom
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tl_half"), // tl
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_tr_half"), // tr
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_t_1"), // top
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_l"), // left
								SpriteImageObjectFactory.getInstance()
										.getImageRefId(
												"vx_flex_border_r") // right
					},
						new int[] {
								GlobalConsts.INT_005, // top
								GlobalConsts.INT_005, // left
								GlobalConsts.INT_005, // bottom
								GlobalConsts.INT_005 // right
					}
					));
			break;
		}
	}
	/**
	 * Updates all labels.
	 * @param pc the {@link DWCharacter} displayed
	 */
	protected void update(final DWCharacter pc) {
		try {
			PooledStringBuilder sb =
					StringBuilderPool.getInstance().getStringBuilder();
			if (pc == null
					|| (pc != null && pc.getProfession() < 0)) {
				lblAttack.setText("");
				lblDefense.setText("");
				lblEvasion.setText("");
				lblStealth.setText("");
				lblPerception.setText("");
				sb.append("the character's awareness of ");
				sb.append("his or her surroundings");
				lblPER.setTooltipText(sb.toString());
				lblMA.setText("");
				lblMagicalAttack.setBorder(null);
				lblMagicalAttack.setText("");
				lblMagicalDefense.setText("");
			} else {
				lblAttack.setText(Integer.toString(pc.getFullAttack()));
				lblDefense.setText(Integer.toString(pc.getFullDefence()));
				lblEvasion.setText(Integer.toString(pc.getFullEvasion()));
				lblStealth.setText(Integer.toString(pc.getFullStealth()));
				lblPerception.setText(Integer.toString(pc.getFullPerception()));
				sb.append("the character's awareness of ");
				sb.append(DWConsts.GENDER_POSSESSIVE[pc.getGender()]);
				sb.append(" surroundings");
				lblPER.setTooltipText(sb.toString());
				lblMA.setText("Magical Attack");
				if (lblMagicalAttack.getBorder() == null) {
					lblMagicalAttack.setBorder(
							new StatsBorder(lblMagicalAttack));
				}
				lblMagicalAttack.setText(
						Integer.toString(pc.getFullMagicalAttack()));
				lblMagicalDefense.setText(
						Integer.toString(pc.getFullMagicalDefence()));
			}
			sb.returnToPool();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
}
